#!/usr/bin/python

import formDailiesData as fdd
from time import time, sleep, strftime
from ConfigParser import RawConfigParser
from threading import Thread
from wx.lib.stattext import GenStaticText
from wxPython.wx import wxMenu, wxMenuBar, wxNewId, wxPasswordEntryDialog
from loginDialog import LoginDialog
from settingsDialog import SettingsDialog
from datetime import datetime
from ritzWin import RitzBrowser
from random import shuffle, uniform
from wx import Colour, Frame, AcceleratorTable, ListCtrl, StaticLine, Button, Image, BitmapButton, BoxSizer, TextCtrl, StaticText, Panel, Font, PostEvent, NewId, PyEvent, App, Point
from wx import HORIZONTAL, VERTICAL, CENTER, LEFT, RIGHT, BOTTOM, EVT_MOVE, EVT_CLOSE, EVT_MENU, ACCEL_CTRL, LC_REPORT, BORDER_SUNKEN, TE_MULTILINE, TE_READONLY, SWISS, NORMAL, BOLD, EXPAND, EVT_BUTTON, TOP, BITMAP_TYPE_ANY

import logging
logger = logging.getLogger('logfile')
hdlr = logging.FileHandler('logfile.log')
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
hdlr.setFormatter(formatter)
logger.removeHandler(hdlr)

detailedLogger = logging.getLogger('detLog')
hdlr = logging.FileHandler('detLog.log')
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
hdlr.setFormatter(formatter)
detailedLogger.addHandler(hdlr) 
detailedLogger.setLevel(logging.DEBUG)
detailedLogger.removeHandler(hdlr)

LOGIN_ID = wxNewId()
SETTINGS_ID = wxNewId()
ID_FILE_EXIT = wxNewId()
SAVE_SETTINGS_ID = wxNewId()
GRAY    = (150,150,150)
GREEN   = (100,250,100)
YELLOW  = (250,200,0)
GREENCOLOR   = Colour(100,250,100)

def summaryLog( inputToLog ):
  logger.info(inputToLog)
  detailedLogger.info(inputToLog)

def getTimestamp():
  return datetime.now().strftime("%Y-%m-%d %H:%M:%S")

class MyFrame(Frame):
  def __init__(self, parent, id, title, testMode):
    def initSelf():
      Frame.__init__(self, parent, id, title, size=(850, 570))
    initSelf()

    def createFileMenu():
      file_menu = wxMenu()
      file_menu.Append(LOGIN_ID, 'Login')
      file_menu.Append(SAVE_SETTINGS_ID, 'Save Config')
      file_menu.AppendSeparator()
      file_menu.Append(ID_FILE_EXIT, 'Exit Program')
      settings_menu = wxMenu()
      settings_menu.Append(SETTINGS_ID, 'Settings')
      menu_bar = wxMenuBar()
      menu_bar.Append(file_menu, 'File')
      menu_bar.Append(settings_menu, 'Edit')
      self.SetMenuBar(menu_bar)
      EVT_MENU(self, ID_FILE_EXIT, self.close)
      EVT_MENU(self, LOGIN_ID, self.doLoginDialog)
      EVT_MENU(self, SETTINGS_ID, self.doSettingsDialog)
      EVT_MENU(self, SAVE_SETTINGS_ID, self.saveSettings)

    def createKeyboardShortcuts():
      accel_tbl = AcceleratorTable([
            (ACCEL_CTRL, ord('Q'), ID_FILE_EXIT ), 
            (ACCEL_CTRL, ord('S'), SAVE_SETTINGS_ID ), 
            (ACCEL_CTRL, ord('E'), SETTINGS_ID ), 
            (ACCEL_CTRL, ord('L'), LOGIN_ID)])
      self.SetAcceleratorTable(accel_tbl)

    def createListArea():
      self.execListBox = ListCtrl(panel, -1, style=LC_REPORT|BORDER_SUNKEN, size=(150,470))
      self.notExecListBox = ListCtrl(panel, -1, style=LC_REPORT|BORDER_SUNKEN, size=(150,500) )
      self.execListBox.InsertColumn(0, "Daily")
      self.execListBox.InsertColumn(1, "Last Attempt")
      self.notExecListBox.InsertColumn(0, "Daily")
      self.notExecListBox.InsertColumn(1, "Last Attempt")
      for index, row in enumerate(getSetting('def','execchoices')):
        self.execListBox.InsertStringItem(index, row)
        self.execListBox.SetStringItem(index, 1, '')
      for index, row in enumerate(getSetting('def','notexecchoices')):
        self.notExecListBox.InsertStringItem(index, row)
        self.notExecListBox.SetStringItem(index, 1, '')
      self.startButton = Button(panel, 1, 'Start')
      diceFile = 'dice.gif'
      diceImage = Image(diceFile, BITMAP_TYPE_ANY).ConvertToBitmap()
      self.randomizeButton = BitmapButton(panel, 2, bitmap=diceImage, size=(50,35))
      self.moveRightButton = Button(panel, 14, '>', size=(35,35))
      self.moveLeftButton  = Button(panel, 15, '<', size=(35,35))
      self.modeButton  = Button(panel, 99, 'Sched', size=(50,35))
      blankSpace = StaticText(panel, size=(0,150))
      blankSpace2 = StaticText(panel, size=(0,250))

      listArea = BoxSizer(HORIZONTAL)
      execListCol = BoxSizer(VERTICAL)
      execListCol.Add(self.execListBox, border=1)
      hbox = BoxSizer(HORIZONTAL)
      hbox.Add(self.startButton,border = 8, flag=CENTER|LEFT|RIGHT)
      hbox.Add(self.randomizeButton, border = 10, flag=CENTER)
      execListCol.Add(hbox)
      listArea.Add(execListCol, border=10)
      listButtons = BoxSizer(VERTICAL)
      listButtons.Add(blankSpace, flag=CENTER, border=10)
      listButtons.Add(self.moveRightButton, flag=CENTER, border=10)
      listButtons.Add(self.moveLeftButton, flag=CENTER, border=10)
      listButtons.Add(blankSpace2, flag=CENTER, border=10)
      listButtons.Add(self.modeButton, flag=CENTER, border=10)
      listArea.Add(listButtons,border = 10, flag=CENTER)
      listArea.Add(self.notExecListBox, border=1)
      return listArea

    def createLogArea(panel):
      self.bankTotal = StaticText(panel, -1, '??????')
      self.shopSpace = StaticText(panel, -1, '??????')
      self.currentPet = StaticText(panel, -1, '_NAME_')
      self.petHunger = StaticText(panel, -1, '_HUNGER_')
      self.petMood = StaticText(panel, -1, '_MOOD_')
      self.rewardBox = TextCtrl(panel, 10, "[%s] Rewards so far:" % (getTimestamp()), size=(500,200), style = TE_MULTILINE|TE_READONLY)
      font = Font(8, SWISS, NORMAL, NORMAL, False, 'Arial')
      self.rewardBox.SetFont(font)
      self.logBox = TextCtrl(panel, 10, "[%s] Started Ritzwin's Daily Doer" % (getTimestamp()), size=(500,200), style = TE_MULTILINE|TE_READONLY)
      self.logBox.SetFont(font)

      innerVbox2 = BoxSizer(VERTICAL)

      self.mode = StaticText(panel, -1, 'Manual')
      innerHbox = BoxSizer(HORIZONTAL)
      staticCol = BoxSizer(VERTICAL)
      dynamicCol = BoxSizer(VERTICAL)
      staticCol.Add(StaticText(panel, -1, 'Current Pet:'))
      dynamicCol.Add(self.currentPet, border=10)
      staticCol.Add(StaticText(panel, -1, 'Pet Hunger:'))
      dynamicCol.Add(self.petHunger, border=10)
      staticCol.Add(StaticText(panel, -1, 'Pet Mood:'))
      dynamicCol.Add(self.petMood, border=10)
      staticCol.Add(StaticText(panel, -1, 'Bank Total:'))
      dynamicCol.Add(self.bankTotal, border=10)
      staticCol.Add(StaticText(panel, -1, 'Shop Space:'))
      dynamicCol.Add(self.shopSpace, border=10)
      staticCol.Add(StaticText(panel, -1, 'DD Mode:'))
      dynamicCol.Add(self.mode, border=10)
      innerHbox.Add(staticCol, border=20, flag=RIGHT)
      innerHbox.Add(dynamicCol, border=20, flag=RIGHT)


      innerVbox2.Add(self.rewardBox, border=10)
      innerVbox2.Add(self.logBox, border=10)

      innerVbox2.Add(innerHbox, border=10)

      return innerVbox2

    with open('userAgent.txt','r') as f:
      self.userAgent = f.read().strip()
    self.br = RitzBrowser(self.userAgent, testMode)

    panel = Panel(self)

    panel.Centre()
    hbox = BoxSizer(VERTICAL)
    vbox = BoxSizer(HORIZONTAL)

    self.currentUser = None
    if testMode:
      playerLabel = 'TESTMODE'
      self.currentUser = 'TESTMODE'
    else:
      playerLabel = None
    self.playerNameBox = StaticText(panel, -1, playerLabel or 'NOT LOGGED IN')
    self.playerNameBox.SetForegroundColour((255,0,0))
    self.npBox = StaticText(panel, -1, '??? NP')
    self.userAgentBox = StaticText(panel, -1, "User-Agent: %s" % self.userAgent)
    self.userAgentBox.SetFont( Font(6, SWISS, NORMAL, BOLD, False,'MS Shell Dlg 2'))

    vbox.Add(createListArea(), border=5)
    vbox.Add(createLogArea(panel))

    hboxPlayer = BoxSizer(HORIZONTAL)
    vbox.Add((-1, 10))
    hboxPlayer.Add(StaticText(panel, -1, 'Player: '), flag=EXPAND|LEFT|RIGHT|TOP, border=1)
    hboxPlayer.Add(self.playerNameBox, flag=EXPAND|LEFT|RIGHT|TOP, border=1)
    hboxPlayer.Add((150, -1))
    hboxPlayer.Add(self.npBox, flag=EXPAND|LEFT|RIGHT|TOP, border=1)
    hboxPlayer.Add((50, -1))
    hboxPlayer.Add(self.userAgentBox, flag=EXPAND|LEFT|RIGHT|TOP, border=1)
    hbox.Add(hboxPlayer)
    hbox.Add(vbox)
    panel.SetSizer(hbox)
    self.Bind(EVT_BUTTON, self.putInRight, id=14)
    self.Bind(EVT_BUTTON, self.randomizeItemOrdering, id=2)
    self.Bind(EVT_BUTTON, self.putInLeft, id=15)
    self.Bind(EVT_BUTTON, self.start, id=1)
    self.Bind(EVT_BUTTON, self.modeSwitch, id=99)
    self.Bind(EVT_CLOSE, self.close)

    self.startButton.SetFocus()
    EVT_RESULT(self, self.doResult)

    self.testMode = testMode
    self.worker = None
    self.schedule_worker = None

    createFileMenu()
    createKeyboardShortcuts()
    self.updateTimes()


  def updateTimes(self):
    def updateFor(box):
      count = box.GetItemCount()
      user = self.currentUser or 'TESTMODE'
      for i in range(count):
        item = box.GetItemText(i)
        ts = int(getSetting(user, item, 'raw', box.GetItemText(i)))
        lastPlayed = datetime.fromtimestamp(ts)
        box.SetStringItem(i, 1, str(lastPlayed.strftime('%H:%M %d-%m')))
        box.SetItemFont(i, Font(6, SWISS, NORMAL, BOLD, False,'MS Shell Dlg 2'))
        box.SetItemBackgroundColour(i,GREEN)
        freq = fdd.dailyData[str(item)]['freq']
        if freq == 'daily':
          sameDay = lastPlayed.strftime('%j') == datetime.fromtimestamp(int(time())).strftime('%j')
          if sameDay:
            box.SetItemBackgroundColour(i,GRAY)
        else:
          minuteDiff = (int(time()) - ts)/60
          if minuteDiff<int(freq):
            box.SetItemBackgroundColour(i,YELLOW)

    updateFor(self.execListBox)
    updateFor(self.notExecListBox)


  def modeSwitch(self, *args):
    if self.modeButton.GetLabel() == 'Sched':
      self.modeButton.SetLabel('Man')
      self.mode.SetLabel('Schedule')
      self.doScheduleMode(self)
    else:
      self.modeButton.SetLabel('Sched')
      self.mode.SetLabel('Manual')
      self.endScheduleMode()


  def doScheduleMode(self, event):
    sleep(0.20)
    if self.schedule_worker:
      self.schedule_worker.abort()
      return

    self.startButton.SetLabel('ScheduleMode')
    itemsList = []
    self.schedule_worker = ScheduleThread(self, self.br)


  def endScheduleMode(self):
    self.schedule_worker.abort()
    self.schedule_worker = None
    self.startButton.SetLabel('Start')


  def getAvailableDailies(self):
    availableList = []
    for i in range(self.execListBox.GetItemCount()):
      if self.execListBox.GetItemBackgroundColour(i) == GREENCOLOR:
        availableList.append( self.execListBox.GetItemText(i) )
    return availableList

  def saveSettings(self, event, settingsDict={}):
    execChoices = [self.execListBox.GetItemText(index) for index in range(self.execListBox.GetItemCount())]
    notExecChoices = [self.notExecListBox.GetItemText(index) for index in range(self.notExecListBox.GetItemCount())]

    config = RawConfigParser()
    config.read('settings.cfg')
    if 'def' not in config.sections():
      config.add_section('def')

    for e in settingsDict:
      config.set('def', e, settingsDict[e])

    config.set('def', 'execchoices', execChoices)
    config.set('def', 'notexecchoices', notExecChoices)
    with open('settings.cfg','wb') as f:
      config.write(f)


  def close(self, event):
    for worker in [self.worker, self.schedule_worker]:
      if worker:
        try:
          worker.abort()
	except RuntimeError:
          pass
    try:
      self.Close()
    except RuntimeError:
      pass
    try:
      self.Destroy()
    except RuntimeError:
      pass

  def doResult(self, event):
    data = eval(str(event.data))
    for item in data:
      if 'sleep' in data[item]:
        self.updateLogBox( 'Waiting for [%s] seconds.' % data[item]['sleep'] )
      if 'pageSleep' in data[item]:
        self.updateLogBox( 'Waiting before %s for [%s] seconds.' % (item, data[item]['pageSleep']) )
      if 'timeEst' in data[item]:
        self.updateLogBox( 'Estimated wait time for %s is [%s] seconds.' % (item, data[item]['timeEst']) )
      if 'hunger' in data[item]:
        self.updatePetHunger( data[item]['hunger'] )
      if 'mood' in data[item]:
        self.updatePetMood( data[item]['mood'] )
      if 'currentPet' in data[item]:
        self.updateCurrentPet( data[item]['currentPet'] )
      if 'reward' in data[item]:
        self.updateRewardBox( data[item]['reward'], item )
      if 'complete' in data[item]:
        self.worker = None
        self.startButton.SetLabel('Start')
      if 'stopSchedule' in data[item]:
        if self.schedule_worker:
          self.schedule_worker.abort()
          self.schedule_worker = None
        self.startButton.SetLabel('Start')
      if 'stop' in data[item]:
        self.worker.abort()
        self.worker = None
        self.startButton.SetLabel('Start')
      if 'np' in data[item]:
        self.updateNPBox(data[item]['np'])
      if 'bankTotal' in data[item]:
        self.updateBankTotal( data[item]['bankTotal'] )
      if 'shopSpace' in data[item]:
        self.updateShopSpace( data[item]['shopSpace'] )
      if 'chgUser' in data[item]:
        self.changeUserInSchedule(data[item]['chgUser'])
    self.updateTimes()


  def updateNPBox(self, newNP):
    self.npBox.SetLabel("%s NP" % newNP)

  def updatePetMood(self, mood):
    self.petMood.SetLabel("%s" % mood)

  def updatePetHunger(self, hunger):
    self.petHunger.SetLabel("%s" % hunger)

  def updateCurrentPet(self, petName):
    self.currentPet.SetLabel("%s" % petName)

  def updateBankTotal(self, bankTotal):
    self.bankTotal.SetLabel("%s" % str(bankTotal))

  def updateShopSpace(self, shopSpace):
    self.shopSpace.SetLabel("%s" % str(shopSpace))

  def getRunInfo(self, start_time):
    player = self.playerNameBox.GetLabel()
    bankTotal = self.bankTotal.GetLabel()
    shopSpace = self.shopSpace.GetLabel()
    pet = self.currentPet.GetLabel()
    petHunger = self.petHunger.GetLabel()
    currentNP = self.npBox.GetLabel()
    end_time = time()
    total_time = (int(end_time) - int(start_time))/60
    return "%s: NP: %s+%s, \nShop Space: %s, %s hunger: %s \nRun time: %smins" % (player, bankTotal, currentNP, shopSpace, pet, petHunger, str(total_time))


  def doSleep(self, seconds):
    if not self.testMode:
      sleep(seconds)


  def start(self, event):
    sleep(0.25)
    if self.worker:
      self.worker.abort()
      return

    if self.startButton.GetLabel() == 'Start':
      self.startButton.SetLabel('Stop')
      self.worker = WorkerThread(self, self.getDailiesListToDo(), self.br)

  def resetAllLabels(self):
    self.updateNPBox('')
    self.updatePetMood('')
    self.updatePetHunger('')
    self.updateCurrentPet('')
    self.updateBankTotal('')
    self.updateShopSpace('')


  def getDailiesListToDo(self):
    itemsList = []
    for index in range(self.execListBox.GetItemCount()):
      item = str(self.execListBox.GetItemText(index) )
      if item in self.getAvailableDailies():
        itemsList.append(item)
    return itemsList


  def changeUserInSchedule(self, user):
    self.randomizeItemOrdering(self)
    self.currentUser = user
    self.changePlayersName(self.currentUser)
    self.updateTimes()
    newDailiesList = self.getDailiesListToDo()
    self.schedule_worker.setDailiesList(newDailiesList)


  def putInRight(self, event):
    self.swapListCtrlObjects( self.execListBox, self.notExecListBox )
    self.updateTimes()

  def putInLeft(self, event):
    self.swapListCtrlObjects( self.notExecListBox, self.execListBox )
    self.updateTimes()

  def swapListCtrlObjects(self, fromList, toList):
    selectedIndexes = [index for index in range(fromList.GetItemCount()) if fromList.IsSelected(index)]
    selectedIndexes.reverse()
    movingObjects = []
    for i in selectedIndexes:
      movingObjects.append( fromList.GetItemText(i) )
      fromList.DeleteItem(i)
    for i in movingObjects:
      toList.InsertStringItem(0,i)

  def randomizeItemOrdering(self, event):
    l = [self.execListBox.GetItemText(i) for i in range(self.execListBox.GetItemCount())]
    shuffle(l)
    self.execListBox.DeleteAllItems()
    for item in l:
      self.execListBox.InsertStringItem(0,item)
    self.updateTimes()



  def doLoginDialog(self, event):
    config = RawConfigParser()
    config.read('settings.cfg')
    playersD = {}
    for section in config.sections():
      if section!='def':
        user = section
        pw    = ''
        proxy = ''
        schedule = ''
        numComplete = 0
        for i in range(self.execListBox.GetItemCount()):
          item = self.execListBox.GetItemText(i)
          ts = int(getSetting(user, item, 'raw', self.execListBox.GetItemText(i)))
          lastPlayed = datetime.fromtimestamp(ts)
          freq = fdd.dailyData[str(item)]['freq']
          if freq == 'daily':
            sameDay = lastPlayed.strftime('%j') == datetime.fromtimestamp(int(time())).strftime('%j')
            if not sameDay:
              numComplete += 1
          else:
            minuteDiff = (int(time()) - ts)/60
            if minuteDiff>int(freq):
              numComplete += 1

        if 'password' in [i[0] for i in config.items(user)]:
          pw   = str(config.get(user,'password'))
        if 'proxy' in [i[0] for i in config.items(user)]:
          proxy    = str(config.get(user,'proxy'))
        if 'schedule' in [i[0] for i in config.items(user)]:
          schedule = str(config.get(user,'schedule'))
        playersD[user] = {'password' : pw,'proxy' : proxy, 'schedule' : schedule, 'numComplete' : numComplete}
    dia = LoginDialog(None, 'Login / Create new user', '', playersD, getSetting('def', 'lastloadedplayer', 'raw'), self.br, self.getPageSleepTime())
    dia.ShowModal()
    loginInfo = dia.GetResult()
    if loginInfo[0] is not None:
      self.currentUser = loginInfo[0]
      self.changePlayersName(self.currentUser)
    elif loginInfo[1] == 'Failed Login':
      self.playerNameBox.SetLabel('NOT LOGGED IN')
      self.playerNameBox.SetForegroundColour((255,0,0))
    dia.Destroy()
    self.updateTimes()
    self.updateNPBox(self.br.getNP())


  def changePlayersName(self, newName):
    self.playerNameBox.SetLabel('%s' % self.currentUser)
    self.playerNameBox.SetForegroundColour((0,255,0))


  def doSettingsDialog(self, event):
    dia = SettingsDialog(None)
    dia.ShowModal()
    self.saveSettings(None, dia.getAllSettings())
    dia.Destroy()


  def getBetweenDailysTime(self):
    return uniform( float(getSetting('def', 'betweendailiesmin')), float(getSetting('def', 'betweendailiesmax')) )


  def getLongerSleepTime(self):
    return uniform( float(getSetting('def', 'longerDelayMin')), float(getSetting('def', 'longerDelayMax')) )


  def getPageSleepTime(self):
    return uniform( float(getSetting('def', 'pageMin')), float(getSetting('def', 'pageMax')) )


  def updateLogBox(self, newLine ):
    self.logBox.write( '\n[%s] %s' % (getTimestamp(), newLine) )


  def updateRewardBox(self, newLine, daily ):
    self.rewardBox.write('\n[%s] %s -> %s' % (getTimestamp(), daily, newLine) )




class WorkerThread(Thread):
  def __init__(self, notify_window, dailyToDo, br):
    Thread.__init__(self)
    self._notify_window = notify_window
    self._want_abort = 0
    self.dailyToDo = dailyToDo
    self.br = br
    self.start()


  def run(self):
    return self._run()


  def _run(self):
    self.start_time = time()
    self._notify_window.resetAllLabels()
    for item in self.dailyToDo:
      def logSleep( sleepSeconds ):
        PostEvent(self._notify_window, ResultEvent({item:{'sleep': round(sleepSeconds,2)}}))
      if self._want_abort:
        PostEvent(self._notify_window, ResultEvent({'buttonEvent':{'stop':-1}}))
        return
      start_time = time()
      detailedLogger.info('Start %s' % item)

      betweenGets = self._notify_window.getBetweenDailysTime()
      waitTime = self._notify_window.getPageSleepTime()
      longerWaitTime = self._notify_window.getLongerSleepTime()
      PostEvent(self._notify_window, ResultEvent({item:{'pageSleep':round(betweenGets,2)}}))
      response = ''
      if not self._notify_window.testMode:
        sleep( betweenGets )
      if item == 'Tombola': 
        logSleep(waitTime)
        response = self.br.getTombola( waitTime )
      elif item == 'Merry Go Round': 
        waitTimes = [self._notify_window.getPageSleepTime() for i in range(6)]
        PostEvent(self._notify_window, ResultEvent({item:{'timeEst' : str(round(eval(''.join(["+%s" % wt for wt in waitTimes])),2)) }} ))
        response = self.br.getMerryGoRound( waitTimes )
      elif item == 'Shrine': 
        logSleep(waitTime)
        response = self.br.getShrine( waitTime )
      elif item == 'Check mail': 
        waitTimes = [self._notify_window.getPageSleepTime() for i in range(50)]
        PostEvent(self._notify_window, ResultEvent({item:{'timeEst' : str(round(eval(''.join(["+%s" % wt for wt in waitTimes])),2)) }} ))
        response = self.br.checkMail( waitTimes )
      elif item == 'Food club': 
        waitTimes = [self._notify_window.getPageSleepTime() for i in range(13)]
        PostEvent(self._notify_window, ResultEvent({item:{'timeEst' : str(round(eval(''.join(["+%s" % wt for wt in waitTimes])),2)) }} ))
        response = self.br.getFoodClub( waitTimes ,1,1)
      elif item == 'Altador': 
        waitTimes = [self._notify_window.getPageSleepTime() for i in range(3)]
        PostEvent(self._notify_window, ResultEvent({item:{'timeEst' : str(round(eval(''.join(["+%s" % wt for wt in waitTimes])),2)) }} ))
        response = self.br.getAltador( waitTimes )
      elif item == 'Slug': 
        logSleep(waitTime)
        response = self.br.getSlug( waitTime )
      elif item == 'Omelette': 
        logSleep(waitTime)
        response = self.br.getOmelette( waitTime )
        if getSetting('def', 'eatomelette'):
          PostEvent(self._notify_window, ResultEvent({item:{'reward':response,'np':self.br.getNP()}}))
          PostEvent(self._notify_window, ResultEvent({item:{'pageSleep':round(betweenGets,2)}}))
          waitTime2 = self._notify_window.getPageSleepTime()
          logSleep(waitTime2)
          waitTimesList = [self._notify_window.getPageSleepTime() for i in range(7)]
          PostEvent(self._notify_window, ResultEvent({'Feed Omelette':{'timeEst':str(round(eval(''.join(["+%s" % wt for wt in waitTimesList])),2)) }}))
          try:
            omelette = response.split('.')[0]
            response = self.br.getFeedOmelette(waitTimesList, omelette, self.br.getCurrentPet())
          except:
            response = "Failed to feed pet omelette, probably didn't get omelette"
      elif item == 'Anchor': 
        logSleep(waitTime)
        response = self.br.getAnchor( waitTime )
      elif item == 'Bob4Apples': 
        logSleep(waitTime)
        response = self.br.getBobApples( waitTime )
      elif item == 'Ice Scratch Card': 
        logSleep(waitTime)
        response = self.br.getIceScratchCard( waitTime )
      elif item == 'Desert Scratch Card': 
        logSleep(waitTime)
        response = self.br.getDesertScratchCard( waitTime )
      elif item == 'Halloween Scratch Card' : 
        logSleep(waitTime)
        response = self.br.getHalloweenScratchCard( waitTime )
      elif item == 'Fruit Machine': 
        logSleep(waitTime)
        response = self.br.getFruitMachine( waitTime )
      elif item == 'Plushie Of Prosperity' : 
        logSleep(waitTime)
        response = self.br.getPlushieOfProsperity( waitTime )
      elif item == 'Fishing': 
        logSleep(waitTime)
        response = self.br.getFishing( waitTime )
      elif item == 'Healing Springs': 
        logSleep(waitTime)
        response = self.br.getHealingSprings( waitTime )
      elif item == 'Jelly': 
        logSleep(waitTime)
        response = self.br.getJelly( waitTime )
      elif item == 'Wheel of Excitement': 
        logSleep(waitTime)
        response = self.br.getWheelOfExcitement( waitTime )
      elif item == 'Snowager': 
        logSleep(waitTime)
        response = self.br.getSnowager( waitTime )
      elif item == 'Trivia Question': 
        logSleep(waitTime)
        response = self.br.getTriviaQuestion( waitTime )
      elif item == 'Forgotten Shore': 
        logSleep(waitTime)
        response = self.br.getForgottenShore( waitTime )
      elif item == 'Wishing Well': 
        waitTimes = [self._notify_window.getPageSleepTime() for i in range(10)]
        PostEvent(self._notify_window, ResultEvent({item:{'timeEst' : str(round(eval(''.join(["+%s" % wt for wt in waitTimes])),2)) }} ))
        response = self.br.getWishingWell( waitTimes, getSetting('def', 'wellamount'), getSetting('def', 'wellwish') )
      elif item == 'Toy Chest': 
        logSleep(waitTime)
        response = self.br.getToyChest( waitTime )
      elif item == 'Bank Interest': 
        logSleep(waitTime)
        response = self.br.getBankInterest( waitTime )
        if getSetting('def', 'extrabankactions'):
          waitTime2 = self._notify_window.getPageSleepTime()
          PostEvent(self._notify_window, ResultEvent({'Deposit Bank':{'timeEst': waitTime2 }}))
          self.br.getBankDeposit( waitTime2, getSetting('def', 'depositmultiplier'), getSetting('def', 'depositifover') )
      elif item == 'Sell Stocks': 
        logSleep(longerWaitTime)
        response = self.br.sellStocks( longerWaitTime, getSetting('def', 'sellstockmin') )
      elif item == 'Wise King': 
        logSleep(longerWaitTime)
        response = self.br.getWiseKing( longerWaitTime )
      elif item == '20x Bagatelle': 
        logSleep(waitTime)
        waitTimes = [self._notify_window.getPageSleepTime()+2 for i in range(21)]
        PostEvent(self._notify_window, ResultEvent({item:{'timeEst' : str(round(eval(''.join(["+%s" % wt for wt in waitTimes])),2)) }} ))
        response = self.br.getBagatelle( waitTime, waitTimes )
      elif item == 'Grumpy King': 
        longerWaitTimes = [self._notify_window.getLongerSleepTime() for i in range(2)]
        est1 = waitTime
        est2 = sum(longerWaitTimes)
        PostEvent(self._notify_window, ResultEvent({item:{'timeEst' : '%s + %s' % (round(est1,2), round(est2,2)) }} ))
        response = self.br.getGrumpyKing( waitTime, longerWaitTimes )
      elif item == 'Buy 1000x Stocks':
        max = getSetting('def', 'buystockmax')
        waitTimes = [self._notify_window.getPageSleepTime() for i in range(3)]
        PostEvent(self._notify_window, ResultEvent({item:{'timeEst' : '%s' % str(round(sum(waitTimes),2)) }} ))
        response = self.br.getStocks( waitTimes, max )
      elif item == 'Lunar Temple': 
        waitTimes = [self._notify_window.getPageSleepTime() for i in range(2)]
        PostEvent(self._notify_window, ResultEvent({item:{'timeEst' : '%s' % str(round(sum(waitTimes),2)) }} ))
        response = self.br.getLunarTemple( waitTimes )
      elif item == 'Meteor': 
        waitTimes = [self._notify_window.getPageSleepTime() for i in range(3)]
        PostEvent(self._notify_window, ResultEvent({item:{'timeEst' : '%s' % str(round(sum(waitTimes),2)) }} ))
        response = self.br.getMeteor( waitTimes )
      elif item == 'Potato Counter': 
        logSleep(longerWaitTime)
        waitTimes = [self._notify_window.getLongerSleepTime() for i in range(3)]
        betweenCountsWait = [self._notify_window.getPageSleepTime() for i in range(3)]
        est1 = sum(waitTimes)
        est2 = sum(betweenCountsWait)
        PostEvent(self._notify_window, ResultEvent({item:{'timeEst' : '%s + %s' % (round(est1,2), round(est2,2)) }} ))
        response = self.br.getPotatoCounter( betweenCountsWait, waitTimes )
      resultDict = {item:{'reward':response,
                                                        'np':self.br.getNP(), 
                                                        'currentPet':self.br.getCurrentPet(), 
                                                        'shopSpace':self.br.getShopSpace(), 
                                                        'hunger' : self.br.getPetHunger(), 
                                                        'mood' : self.br.getPetMood(), 
                                                        'bankTotal' : self.br.getBankTotal()}}
      try:
        PostEvent(self._notify_window, ResultEvent(resultDict))
      except:
        summaryLog('Failed to send post event->\n %s' % (str(resultDict)))
        sleep(5)
        try:
          PostEvent(self._notify_window, ResultEvent(resultDict))
	except:
          summaryLog('Failed to send post event TWICE->\n %s' % (str(resultDict)))
      storeLastVisit(self._notify_window.currentUser, item)
      totalTime = str(int(time()) - int(start_time))
      detailedLogger.info('End %s, total time: %ss' % (item, totalTime))

    if getSetting('def', 'itemsIntoShopAfter'):
      betweenGets = self._notify_window.getBetweenDailysTime()
      PostEvent(self._notify_window, ResultEvent({'Items into shop':{'pageSleep':round(betweenGets,2)}}))
      if not self._notify_window.testMode:
        sleep( betweenGets )
      waitTime = self._notify_window.getPageSleepTime()
      response = self.br.getItemsIntoShop( waitTime )
      PostEvent(self._notify_window, ResultEvent({'Items into shop':{'reward':response,'np':self.br.getNP()}}))

    if getSetting('def', 'auctionItemsFromFile'):
      betweenGets = self._notify_window.getBetweenDailysTime()
      PostEvent(self._notify_window, ResultEvent({'Auctioning items from file':{'pageSleep':round(betweenGets,2)}}))
      if not self._notify_window.testMode:
        sleep( betweenGets )
      waitTimes = [self._notify_window.getPageSleepTime() for i in range(30)]
      PostEvent(self._notify_window, ResultEvent({'Auctioning items':{'timeEst' : 'up to %s' % str(round(sum(waitTimes),2)) }} ))
      response = self.br.getAuctionFromFile( waitTimes )
      PostEvent(self._notify_window, ResultEvent({'Auctioned items':{'reward':response,'np':self.br.getNP()}}))

    if getSetting('def', 'itemsIntoShopAfter') and getSetting('def', 'auctionItemsFromFile'):
      betweenGets = self._notify_window.getBetweenDailysTime()
      PostEvent(self._notify_window, ResultEvent({'Items into shop':{'pageSleep':round(betweenGets,2)}}))
      if not self._notify_window.testMode:
        sleep( betweenGets )
      waitTime = self._notify_window.getPageSleepTime()
      response = self.br.getItemsIntoShop( waitTime )
      PostEvent(self._notify_window, ResultEvent({'Items into shop':{'reward':response,'np':self.br.getNP()}}))



    PostEvent(self._notify_window, ResultEvent({'buttonEvent':{'complete':-1}}))
    summaryLog(self._notify_window.getRunInfo(self.start_time))


  def abort(self):
    self._want_abort = 1

EVT_RESULT_ID = NewId()


class ScheduleThread(WorkerThread):
  def __init__(self, notify_window, br):
    Thread.__init__(self)
    self._notify_window = notify_window
    self._want_abort = 0
    self.br = br
    self.dailyToDo = None
    self.start()


  def run(self):
    while not self._want_abort:
      if self._want_abort:
        PostEvent(self._notify_window, ResultEvent({'buttonEvent':{'stopSchedule':-1}}))
      sleep(.1)
      config = RawConfigParser()
      config.read('settings.cfg')
      for user in config.sections():
        if user!='def':
          schedTime = getSetting(user, 'schedule')
          now = strftime('%H:%M')
          if now == schedTime:
            PostEvent(self._notify_window, ResultEvent({'buttonEvent':{'chgUser':user}}))
            self.br.doLogin(user, getSetting(user, 'password'), getSetting(user, 'proxy'), 4.5)
            while self.dailyToDo is None or self.dailyToDo == []:
              sleep(.1)
              print 'waiting for dailyTodo to be full'

            self._run()
            self.dailyToDo = None


  def setDailiesList(self, dailiesList):
    self.dailyToDo = dailiesList


  def abort(self):
    self._want_abort = 1




def storeLastVisit(player, daily):
  config = RawConfigParser()
  config.read('settings.cfg')
  if player not in config.sections():
    config.add_section(player)
  config.set(player, daily, int(time()))
  config.set('def','lastloadedplayer',player)
  with open('settings.cfg','wb') as f:
    config.write(f)


def EVT_RESULT(win, func):
  win.Connect(-1, -1, EVT_RESULT_ID, func)

class ResultEvent(PyEvent):
  def __init__(self, data):
    PyEvent.__init__(self)
    self.SetEventType(EVT_RESULT_ID)
    self.data = data



def getSetting(section, setting, raw=False, item=False):
  config = RawConfigParser()
  while True:
    try:
      config.read('settings.cfg')
      break
    except Exception as e:
      sleep(.1)
  if raw == 'raw':
    try:
      return str(config.get(section, setting))
    except:
      return 0
  else:
    try:
      return eval(config.get(section, setting))
    except:
      return str(config.get(section, setting))


class MyApp(App):
  def OnInit(self):
    from sys import argv
    testFlag = False
    self.frame = MyFrame(None, -1, "Ritzwin's Daily Doer", testFlag)
    self.frame.Show(True)
    self.frame.SetPosition(Point(100,0))
    return True


if __name__ == '__main__':

  app = MyApp(0)
  app.MainLoop()
